home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 …ember: Reference Library / Dev.CD Dec 00 RL Disk 1.toast / pc / technical documentation / develop / develop issue 26 / develop issue 26 code / truffles - display mgr. / sprocket / experimentalstuff / exceptions.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-15  |  4.1 KB  |  147 lines

  1. /*============================================================
  2.     Exceptions.h
  3.     
  4.     greggor@apple.com
  5. ============================================================*/
  6. #ifndef __EXCEPTIONS__
  7. #define __EXCEPTIONS__
  8. #define Exceptions_h
  9.  
  10. #ifndef __RESOURCES__
  11. #include <Resources.h>
  12. #endif
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #if defined(__MWERKS__)
  19. #define REAL_EXCEPTIONS    // Defiend for compilers that do 'real' exceptions
  20. #endif
  21.  
  22. //
  23. // Our error codes
  24. //
  25. const OSErr ePointerNil                = -110;
  26. const OSErr eGeneralErr                = -1;
  27. const OSErr eAssertionFailure        = -30000;
  28. const OSErr eRequirementNotMet        = -30001;
  29. const OSErr eValueOutOfRange        = -30002;
  30. const OSErr eIndexOutOfRange        = -30003;
  31. const OSErr eLinksCorrupt            = -30004;
  32. const OSErr eDataCorrupt            = -30005;
  33. const OSErr eWrongDataType            = -30006;
  34.  
  35. //
  36. // Constants used by the failure class
  37. //
  38. const long kMagicFailID                = 'fail';
  39.  
  40. const long kTryFrameOnFailureStack    = 0x0001;
  41. const long kExceptionThrown            = 0x0002;
  42. const long kTryInProgress            = 0x0004;
  43. const long kTrySucceeded            = 0x0008;
  44. const long kResignalingFailure        = 0x0010;
  45. const long kTryBlockHasBeenSetup    = 0x0100;
  46.  
  47. #ifndef REAL_EXCEPTIONS
  48.  
  49. #include <setjmp.h>
  50.  
  51. //
  52. // Failure class
  53. //
  54. class TException
  55. {
  56. public:
  57.     TException*                fNext;
  58.     OSErr                    fError;
  59.     long                    fFlags;
  60.     jmp_buf                    fEnv;
  61.     long                    fMagicFailID;
  62.  
  63.                             TException() : fNext(nil), fError(noErr), fFlags(0), fMagicFailID(kMagicFailID) {};
  64.     Boolean                    Setup();
  65.     void                    TearDown();
  66.     Boolean                    BeginTry();
  67.     OSErr                    ExceptionError()        { return fError; };
  68. };
  69.  
  70. //
  71. //  try / catch macros
  72. //
  73. //    Formerly, I used the result of setjmp to set status bits;
  74. //    however, that's not working in MetroWerks.  My guess is that
  75. //    there is some confusion over sizeof(int), but I'm not sure.
  76. //    Therefore, I'm just going to assume that the second time
  77. //    fi.Setup executes, we're failing.
  78. //
  79. #define Try            TException fi; setjmp(fi.fEnv); if(fi.Setup()) while(fi.BeginTry())
  80. #define Catch(err)    else if((err = fi.ExceptionError()) != noErr)
  81.  
  82. //
  83. // Globals:
  84. //
  85. extern TException*            gExceptionStack;
  86.  
  87. //
  88. // Prototypes
  89. //
  90. void                        Throw(OSErr theErr);
  91.  
  92. #else    // REAL_EXCEPTIONS
  93.  
  94. #define Try            try
  95. #define Catch(err)    catch(OSErr err)
  96. #define Throw        throw
  97.  
  98. #endif    // REAL_EXCEPTIONS
  99.  
  100. typedef void (*NotifyFailureProc)(OSErr err);
  101.  
  102. void                        SetExceptionNotifyProc(NotifyFailureProc notifyProc);
  103. Boolean                        ExceptionNotifyProcInstalled(void);
  104. void                        NotifyFailure(OSErr err);
  105.  
  106. void                        MakeVariableNoRegister( void* foo );
  107.  
  108. //
  109. // This macro references the address of the specified local
  110. // variable; this will prevent the compiler from using the
  111. // variable as a register variable.
  112. //
  113. #define NOREGISTER(x)        ( MakeVariableNoRegister( (void*)(&(x)) ) )
  114.  
  115. //
  116. //    Convenience functions
  117. //
  118. inline void Fail()                            { Throw(eGeneralErr); }
  119. inline void FailErr(OSErr theErr)            { if(theErr != noErr) Throw(theErr); }
  120. inline void FailOSErr(OSErr theErr)            { FailErr(theErr); }
  121. inline void FailResError()                    { FailErr(ResError()); }
  122. inline void FailMemError()                    { FailErr(MemError()); }
  123. inline void FailNil(void* ptr)                { if(ptr == nil) Throw(ePointerNil); }
  124. inline void FailNIL(void* ptr)                { FailNil(ptr); }
  125. inline void FailResErrorOrNil(void* ptr)    { FailResError(); FailNil(ptr); }
  126. inline void FailMemErrorOrNil(void* ptr)    { FailMemError(); FailNil(ptr); }
  127.  
  128. //
  129. // Requirements
  130. //
  131. inline void Require(Boolean truth)            { if( !(truth) ) Throw(eRequirementNotMet); }
  132. inline void RequirePtrValid(void* p)        { if( (p == nil) || (((long)(p) & 1) != 0) ) Throw(eRequirementNotMet); }
  133. inline void RequireHandleValid(Handle h)    { RequirePtrValid((void*)(h)); RequirePtrValid((void*)(*h)); }
  134.  
  135. //
  136. // Requirements must always be met, but Assertions can be removed in non-debug builds
  137. // as they are statements that are ASSUMED to always be true
  138. //
  139. inline void Assert(Boolean truth)            { if( !(truth) ) Throw(eAssertionFailure); }
  140. inline void AssertPtrValid(void* p)            { if( (p == nil) || (((long)(p) & 1) != 0) ) Throw(eAssertionFailure); }
  141. inline void AssertHandleValid(void** h)        { AssertPtrValid((void*)h); AssertPtrValid(*h); }
  142.  
  143. #define ASSERT(x) Assert(x)
  144. #define REQUIRE(x) Require(x)
  145.  
  146. #endif
  147.